package task5;

import java.util.LinkedList;
import java.util.Random;

public class MyThreadPool {

	class MyThread implements Runnable {
		private String myTaskName;

		public MyThread(String taskName) {
			myTaskName = "";
			myTaskName = myTaskName.concat(taskName);
		}

		public void run() {
			Random r = new Random();

			System.out.println("Task " + myTaskName + " is started...");

			try {
				Thread.sleep(r.nextInt(THREAD_WAITING_CEILING));
			} catch (InterruptedException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}

			System.out.println("Task " + myTaskName + " is completed successfully!");
		}
	}

	class MyTask implements Runnable {
		private String myName;
		private Thread myThread;

		public MyTask(String name) {
			myName = "";
			myName = myName.concat(name);
		}

		public void run() {
			try {
				myThread = getThread(myName);
				myThread.start();
				myThread.join();
				releaseThread(myThread);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	private final static int THREAD_WAITING_CEILING = 3000;
	private final static int DEFAULT_POOL_CAPACITY = 10;

	private LinkedList<Thread> myThreads;
	private static int MAX_THREADS;

	public MyThreadPool() {
		this(DEFAULT_POOL_CAPACITY);
	}

	public MyThreadPool(int n) {
		MAX_THREADS = n;
		myThreads = new LinkedList<Thread>();
	}

	public Thread getThread(String taskName) throws InterruptedException {
		synchronized (myThreads) {
			while (myThreads.size() == MAX_THREADS) {
				myThreads.wait();
			}
			Thread mt = new Thread(new MyThread(taskName));
			myThreads.add(mt);
			return mt;
		}
	}

	public void releaseThread(Thread t) {
		synchronized (myThreads) {
			myThreads.remove(t);
			myThreads.notify();
		}
	}
}
